/*     */ package com.zimbra.cs.service;
/*     */ 
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.account.Key.ServerBy;
/*     */ import com.zimbra.common.mime.ContentDisposition;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.HttpUtil;
/*     */ import com.zimbra.common.util.L10nUtil;
/*     */ import com.zimbra.common.util.L10nUtil.MsgKey;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.LogFactory;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Config;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.html.BrowserDefang;
/*     */ import com.zimbra.cs.html.DefangFactory;
/*     */ import com.zimbra.cs.mailbox.CalendarItem;
/*     */ import com.zimbra.cs.mailbox.MailItem;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxManager;
/*     */ import com.zimbra.cs.mailbox.Message;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.mailbox.calendar.CalendarMailSender;
/*     */ import com.zimbra.cs.mailbox.calendar.Invite;
/*     */ import com.zimbra.cs.mailbox.util.TagUtil;
/*     */ import com.zimbra.cs.mime.Mime;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.servlet.ZimbraServlet;
/*     */ import com.zimbra.cs.util.AccountUtil;
/*     */ import java.io.ByteArrayInputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.internet.MimeMessage;
/*     */ import javax.mail.internet.MimePart;
/*     */ import javax.servlet.RequestDispatcher;
/*     */ import javax.servlet.ServletContext;
/*     */ import javax.servlet.ServletException;
/*     */ import javax.servlet.ServletOutputStream;
/*     */ import javax.servlet.http.HttpServletRequest;
/*     */ import javax.servlet.http.HttpServletResponse;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class ContentServlet
/*     */   extends ZimbraServlet
/*     */ {
/*     */   private static final long serialVersionUID = 6466028729668217319L;
/*     */   public static final String SERVLET_PATH = "/service/content";
/*     */   public static final String PREFIX_GET = "/get";
/*     */   protected static final String PREFIX_PROXY = "/proxy";
/*     */   public static final String PARAM_MSGID = "id";
/*     */   protected static final String PARAM_UPLOAD_ID = "aid";
/*     */   protected static final String PARAM_PART = "part";
/*     */   protected static final String PARAM_FORMAT = "fmt";
/*     */   protected static final String PARAM_DUMPSTER = "dumpster";
/*     */   protected static final String PARAM_SYNC = "sync";
/*     */   protected static final String PARAM_EXPUNGE = "expunge";
/*     */   protected static final String PARAM_LOCALE_ID = "loc";
/*     */   protected static final String FORMAT_RAW = "raw";
/*     */   protected static final String FORMAT_DEFANGED_HTML = "htmldf";
/*     */   protected static final String FORMAT_DEFANGED_HTML_NOT_IMAGES = "htmldfi";
/*     */   protected static final String CONVERSION_PATH = "/extension/convertd";
/*     */   protected static final String ATTR_MIMEPART = "mimepart";
/*     */   protected static final String ATTR_MSGDIGEST = "msgdigest";
/*     */   protected static final String ATTR_CONTENTURL = "contenturl";
/*     */   protected static final String MSGPAGE_BLOCK = "errorpage.attachment.blocked";
/* 101 */   private String mBlockPage = null;
/*     */   
/* 103 */   private static Log mLog = LogFactory.getLog(ContentServlet.class);
/*     */   
/*     */   private void getCommand(HttpServletRequest req, HttpServletResponse resp, AuthToken token) throws ServletException, IOException
/*     */   {
/* 107 */     ItemId iid = null;
/*     */     try {
/* 109 */       iid = new ItemId(req.getParameter("id"), (String)null);
/*     */     } catch (ServiceException e) {
/* 111 */       resp.sendError(400, L10nUtil.getMessage(L10nUtil.MsgKey.errInvalidId, req, new Object[0]));
/* 112 */       return;
/*     */     }
/*     */     
/* 115 */     String part = req.getParameter("part");
/* 116 */     String fmt = req.getParameter("fmt");
/* 117 */     String dumpsterParam = req.getParameter("dumpster");
/* 118 */     boolean fromDumpster = (dumpsterParam != null) && (!dumpsterParam.equals("0")) && (!dumpsterParam.equalsIgnoreCase("false"));
/*     */     
/*     */     try
/*     */     {
/* 122 */       if (!iid.isLocal())
/*     */       {
/* 124 */         proxyServletRequest(req, resp, iid.getAccountId());
/*     */       }
/*     */       else
/*     */       {
/* 128 */         String authId = token.getAccountId();
/* 129 */         String accountId = iid.getAccountId() != null ? iid.getAccountId() : authId;
/* 130 */         AccountUtil.addAccountToLogContext(Provisioning.getInstance(), accountId, "name", "id", token);
/* 131 */         if (!accountId.equalsIgnoreCase(authId)) {
/* 132 */           ZimbraLog.addToContext("aid", authId);
/*     */         }
/* 134 */         Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(accountId);
/* 135 */         if (mbox == null) {
/* 136 */           resp.sendError(400, L10nUtil.getMessage(L10nUtil.MsgKey.errMailboxNotFound, req, new Object[0]));
/*     */         }
/*     */         else {
/* 139 */           ZimbraLog.addMboxToContext(mbox.getId());
/*     */           
/* 141 */           MailItem item = mbox.getItemById(new OperationContext(token), iid.getId(), MailItem.Type.UNKNOWN, fromDumpster);
/* 142 */           if (item == null) {
/* 143 */             resp.sendError(400, L10nUtil.getMessage(L10nUtil.MsgKey.errMessageNotFound, req, new Object[0]));
/*     */           }
/*     */           else
/*     */             try
/*     */             {
/* 148 */               if (part == null)
/*     */               {
/* 150 */                 boolean sync = "1".equals(req.getParameter("sync"));
/* 151 */                 StringBuffer hdr = new StringBuffer();
/* 152 */                 if (sync)
/*     */                 {
/* 154 */                   resp.addHeader("X-Zimbra-Tags", TagUtil.getTagIdString(item));
/* 155 */                   resp.addHeader("X-Zimbra-Tag-Names", TagUtil.encodeTags(item.getTags()));
/* 156 */                   resp.addHeader("X-Zimbra-Flags", item.getFlagString());
/* 157 */                   resp.addHeader("X-Zimbra-Received", Long.toString(item.getDate()));
/* 158 */                   resp.addHeader("X-Zimbra-Modified", Long.toString(item.getChangeDate()));
/*     */                   
/* 160 */                   hdr.append("X-Zimbra-Tags: ").append(TagUtil.getTagIdString(item)).append("\n");
/* 161 */                   hdr.append("X-Zimbra-Tag-Names: ").append(TagUtil.encodeTags(item.getTags()));
/* 162 */                   hdr.append("X-Zimbra-Flags: ").append(item.getFlagString()).append("\n");
/* 163 */                   hdr.append("X-Zimbra-Received: ").append(item.getDate()).append("\n");
/* 164 */                   hdr.append("X-Zimbra-Modified: ").append(item.getChangeDate()).append("\n");
/*     */                 }
/*     */                 
/* 167 */                 if ((item instanceof Message)) {
/* 168 */                   Message msg = (Message)item;
/* 169 */                   if (sync) {
/* 170 */                     resp.addHeader("X-Zimbra-Conv", Integer.toString(msg.getConversationId()));
/* 171 */                     hdr.append("X-Zimbra-Conv: ").append(msg.getConversationId()).append("\n");
/* 172 */                     resp.getOutputStream().write(hdr.toString().getBytes());
/*     */                   }
/*     */                   
/* 175 */                   resp.setContentType("text/plain");
/* 176 */                   InputStream is = msg.getContentStream();
/* 177 */                   ByteUtil.copy(is, true, resp.getOutputStream(), false);
/* 178 */                 } else if ((item instanceof CalendarItem)) {
/* 179 */                   CalendarItem calItem = (CalendarItem)item;
/* 180 */                   if (sync) {
/* 181 */                     resp.getOutputStream().write(hdr.toString().getBytes());
/*     */                   }
/*     */                   
/* 184 */                   resp.setContentType("text/plain");
/* 185 */                   if (iid.hasSubpart()) {
/* 186 */                     int invId = iid.getSubpartId();
/* 187 */                     MimeMessage mm = calItem.getSubpartMessage(invId);
/* 188 */                     if (mm == null)
/*     */                     {
/* 190 */                       Invite[] invs = calItem.getInvites(invId);
/* 191 */                       if ((invs != null) && (invs.length > 0)) {
/* 192 */                         Invite invite = invs[0];
/* 193 */                         mm = CalendarMailSender.createCalendarMessage(invite);
/*     */                       }
/*     */                     }
/* 196 */                     if (mm != null)
/* 197 */                       mm.writeTo(resp.getOutputStream());
/*     */                   } else {
/* 199 */                     InputStream is = calItem.getRawMessage();
/* 200 */                     if (is != null) {
/* 201 */                       ByteUtil.copy(is, true, resp.getOutputStream(), false);
/*     */                     }
/*     */                   }
/*     */                 }
/*     */               } else {
/* 206 */                 MimePart mp = null;
/* 207 */                 if ((item instanceof Message)) {
/* 208 */                   mp = getMimePart((Message)item, part);
/*     */                 } else {
/* 210 */                   CalendarItem calItem = (CalendarItem)item;
/* 211 */                   if (iid.hasSubpart()) {
/* 212 */                     MimeMessage mbp = calItem.getSubpartMessage(iid.getSubpartId());
/* 213 */                     if (mbp != null)
/* 214 */                       mp = Mime.getMimePart(mbp, part);
/*     */                   } else {
/* 216 */                     mp = getMimePart(calItem, part);
/*     */                   }
/*     */                 }
/* 219 */                 if (mp != null) {
/* 220 */                   String contentType = mp.getContentType();
/* 221 */                   if (contentType == null) {
/* 222 */                     contentType = "application/octet-stream";
/*     */                   }
/* 224 */                   if ((contentType.toLowerCase().startsWith("text/html")) && (("htmldf".equals(fmt)) || ("htmldfi".equals(fmt)))) {
/* 225 */                     sendbackDefangedHtml(mp, contentType, resp, fmt);
/*     */                   }
/* 227 */                   else if (!isTrue("zimbraAttachmentsViewInHtmlOnly", mbox.getAccountId())) {
/* 228 */                     sendbackOriginalDoc(mp, contentType, req, resp);
/*     */                   } else {
/* 230 */                     req.setAttribute("mimepart", mp);
/* 231 */                     req.setAttribute("msgdigest", item.getDigest());
/* 232 */                     req.setAttribute("contenturl", req.getRequestURL().toString());
/* 233 */                     RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/extension/convertd");
/* 234 */                     dispatcher.forward(req, resp);
/*     */                   }
/*     */                 }
/*     */                 else
/*     */                 {
/* 239 */                   resp.sendError(400, L10nUtil.getMessage(L10nUtil.MsgKey.errPartNotFound, req, new Object[0]));
/*     */                 }
/*     */               }
/* 242 */             } catch (MessagingException e) { resp.sendError(500, e.getMessage());
/*     */             }
/*     */         }
/* 245 */       } } catch (MailServiceException.NoSuchItemException e) { resp.sendError(404, L10nUtil.getMessage(L10nUtil.MsgKey.errNoSuchItem, req, new Object[0]));
/*     */     } catch (ServiceException e) {
/* 247 */       returnError(resp, e);
/*     */     } finally {
/* 249 */       ZimbraLog.clearContext();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private void retrieveUpload(HttpServletRequest req, HttpServletResponse resp, AuthToken authToken)
/*     */     throws IOException
/*     */   {
/* 260 */     String uploadId = req.getParameter("aid");
/* 261 */     if (uploadId == null) {
/* 262 */       resp.sendError(400, L10nUtil.getMessage(L10nUtil.MsgKey.errMissingUploadId, req, new Object[0]));
/* 263 */       return;
/*     */     }
/*     */     try
/*     */     {
/* 267 */       if (!FileUploadServlet.isLocalUpload(uploadId))
/*     */       {
/* 269 */         String serverId = FileUploadServlet.getUploadServerId(uploadId);
/* 270 */         Server server = Provisioning.getInstance().get(Key.ServerBy.id, serverId);
/* 271 */         proxyServletRequest(req, resp, server, null);
/* 272 */         return;
/*     */       }
/*     */       
/* 275 */       FileUploadServlet.Upload up = FileUploadServlet.fetchUpload(authToken.getAccountId(), uploadId, authToken);
/* 276 */       if (up == null) {
/* 277 */         resp.sendError(400, L10nUtil.getMessage(L10nUtil.MsgKey.errNoSuchUpload, req, new Object[0]));
/* 278 */         return;
/*     */       }
/*     */       
/* 281 */       String filename = up.getName();
/* 282 */       ContentDisposition cd = new ContentDisposition("attachment").setParameter("filename", filename == null ? "unknown" : filename);
/* 283 */       resp.addHeader("Content-Disposition", cd.toString());
/* 284 */       sendbackOriginalDoc(up.getInputStream(), up.getContentType(), resp);
/*     */       
/* 286 */       boolean expunge = ("true".equalsIgnoreCase(req.getParameter("expunge"))) || ("1".equals(req.getParameter("expunge")));
/* 287 */       if (expunge)
/* 288 */         FileUploadServlet.deleteUpload(up);
/*     */     } catch (ServiceException e) {
/* 290 */       returnError(resp, e);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   private boolean isTrue(String attr, String accountId)
/*     */     throws ServletException
/*     */   {
/* 300 */     Provisioning prov = Provisioning.getInstance();
/*     */     try {
/* 302 */       Account account = prov.get(Key.AccountBy.id, accountId);
/* 303 */       return (prov.getConfig().getBooleanAttr(attr, false)) || (account.getBooleanAttr(attr, false));
/*     */     }
/*     */     catch (ServiceException e) {
/* 306 */       throw new ServletException(e);
/*     */     }
/*     */   }
/*     */   
/*     */   public static MimePart getMimePart(CalendarItem calItem, String part) throws IOException, MessagingException, ServiceException {
/* 311 */     return Mime.getMimePart(calItem.getMimeMessage(), part);
/*     */   }
/*     */   
/*     */   public static MimePart getMimePart(Message msg, String part) throws IOException, MessagingException, ServiceException {
/* 315 */     return Mime.getMimePart(msg.getMimeMessage(), part);
/*     */   }
/*     */   
/*     */   public static void sendbackOriginalDoc(MimePart mp, String contentType, HttpServletRequest req, HttpServletResponse resp) throws IOException, MessagingException
/*     */   {
/* 320 */     String filename = Mime.getFilename(mp);
/* 321 */     if (filename == null)
/* 322 */       filename = "unknown";
/* 323 */     String cd = HttpUtil.createContentDisposition(req, "attachment", filename);
/* 324 */     resp.addHeader("Content-Disposition", cd);
/* 325 */     String desc = mp.getDescription();
/* 326 */     if (desc != null)
/* 327 */       resp.addHeader("Content-Description", desc);
/* 328 */     sendbackOriginalDoc(mp.getInputStream(), contentType, resp);
/*     */   }
/*     */   
/*     */   public static void sendbackOriginalDoc(InputStream is, String contentType, HttpServletResponse resp) throws IOException
/*     */   {
/* 333 */     resp.setContentType(contentType);
/* 334 */     ByteUtil.copy(is, true, resp.getOutputStream(), false);
/*     */   }
/*     */   
/*     */   static void sendbackDefangedHtml(MimePart mp, String contentType, HttpServletResponse resp, String fmt) throws IOException, MessagingException
/*     */   {
/* 339 */     resp.setContentType(contentType);
/* 340 */     InputStream is = null;
/*     */     try {
/* 342 */       String html = DefangFactory.getDefanger(contentType).defang(is = mp.getInputStream(), "htmldf".equals(fmt));
/* 343 */       ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes("utf-8"));
/* 344 */       ByteUtil.copy(bais, false, resp.getOutputStream(), false);
/*     */     } finally {
/* 346 */       ByteUtil.closeStream(is);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private void sendbackBlockMessage(HttpServletRequest req, HttpServletResponse resp)
/*     */     throws ServletException, IOException
/*     */   {
/* 357 */     RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(this.mBlockPage);
/* 358 */     if (dispatcher != null) {
/* 359 */       dispatcher.forward(req, resp);
/* 360 */       return;
/*     */     }
/* 362 */     resp.sendError(403, L10nUtil.getMessage(L10nUtil.MsgKey.errAttachmentDownloadDisabled, req, new Object[0]));
/*     */   }
/*     */   
/*     */   public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
/*     */   {
/* 367 */     ZimbraLog.clearContext();
/* 368 */     addRemoteIpToLoggingContext(req);
/*     */     
/* 370 */     mLog.debug("request url: %s, path info: ", new Object[] { req.getRequestURL(), req.getPathInfo() });
/*     */     
/* 372 */     AuthToken authToken = getAuthTokenFromCookie(req, resp);
/* 373 */     if (authToken == null) {
/* 374 */       return;
/*     */     }
/* 376 */     if (isTrue("zimbraAttachmentsBlocked", authToken.getAccountId())) {
/* 377 */       sendbackBlockMessage(req, resp);
/* 378 */       return;
/*     */     }
/* 380 */     String pathInfo = req.getPathInfo();
/* 381 */     if ((pathInfo != null) && (pathInfo.equals("/get"))) {
/* 382 */       getCommand(req, resp, authToken);
/* 383 */     } else if ((pathInfo != null) && (pathInfo.equals("/proxy"))) {
/* 384 */       retrieveUpload(req, resp, authToken);
/*     */     } else {
/* 386 */       resp.sendError(400, L10nUtil.getMessage(L10nUtil.MsgKey.errInvalidRequest, req, new Object[0]));
/*     */     }
/*     */   }
/*     */   
/*     */   public void init() throws ServletException
/*     */   {
/* 392 */     String name = getServletName();
/* 393 */     mLog.info("Servlet " + name + " starting up");
/* 394 */     super.init();
/* 395 */     this.mBlockPage = getInitParameter("errorpage.attachment.blocked");
/*     */   }
/*     */   
/*     */   public void destroy()
/*     */   {
/* 400 */     String name = getServletName();
/* 401 */     mLog.info("Servlet " + name + " shutting down");
/* 402 */     super.destroy();
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/ContentServlet.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */